<template>
    <el-container>
        <el-aside width="300px" v-loading="menuloading">
            <el-container>
                <el-header>
                    <el-input :placeholder="$t('menu.menuFilterText')" v-model="menuFilterText" clearable></el-input>
                </el-header>
                <el-main class="nopadding">
                    <el-tree ref="menuRef" class="menu" node-key="id" :data="menuList" :props="menuProps" draggable
                        highlight-current :expand-on-click-node="false" check-strictly show-checkbox
                        :filter-node-method="menuFilterNode" @node-click="menuClick" @node-drop="nodeDrop">
                        <template #default="{ node, data }">
                            <span class="custom-tree-node">
                                <span class="label">{{ node.label }}</span>
                                <span class="do">
                                    <el-button icon="el-icon-plus" size="small" @click.stop="add(node, data)"></el-button>
                                </span>
                            </span>
                        </template>
                    </el-tree>
                </el-main>
                <el-footer style="height:51px;">
                    <el-button v-auth="'menu.add'" type="primary" size="small" icon="el-icon-plus" @click="add"></el-button>
                    <el-button v-auth="'menu.delete'" type="danger" size="small" plain icon="el-icon-delete"
                        @click="delMenu"></el-button>
                </el-footer>
            </el-container>
        </el-aside>
        <el-container>
            <el-main class="nopadding" style="padding:20px;" ref="main">
                <save ref="saveRef" :menu="menuList"></save>
            </el-main>
        </el-container>
    </el-container>
</template>
<script setup>
import { ref, reactive, onMounted, watch } from 'vue';
import api from '@/api';
import i18n from '@/locales';
import { ElMessage, ElMessageBox } from 'element-plus';
import save from './save.vue';

// 定义响应数据
let newMenuIndex = ref(1);
const menuloading = ref(false);
const menuList = ref([]);
const menuFilterText = ref('');
const menuRef = ref(null);
const saveRef = ref(null);
const menuProps = reactive({
    label: (data) => data.title,
});
// 定义监听menuFilterText方法
watch(() => menuFilterText.value, (val) => {
    menuRef.value.filter(val);
}, { deep: true });
// 组件挂载时加载数据
onMounted(() => {
    getMenu();
});
// 加载树数据
const getMenu = async () => {
    try {
        menuloading.value = true;
        const res = await api.setting.menu.list.get();
        if (res.code == 200) {
            menuList.value = res.data;
            newMenuIndex.value = res.data.length;
        }
    } catch (error) {
        console.error('Error in setting/menu/index/getMenu action:', error);
    } finally {
        menuloading.value = false;
    }
};
// 树点击
const menuClick = (data, node) => {
    var pid = node.level == 1 ? undefined : node.parent.data.id;
    saveRef.value.setData(data, pid);
    menuRef.value.$el.scrollTop = 0;
};
// 树过滤
const menuFilterNode = (value, data) => {
    if (!value) return true;
    var targetText = data.title;
    return targetText.indexOf(value) !== -1;
};
// 树拖拽
const nodeDrop = async (draggingNode, dropNode, dropType) => {
    try {
        menuloading.value = true;
        saveRef.value.setData({});
        var reqData = {
            dragid: draggingNode.data.id,
            dropid: dropNode.data.id,
            droptype: dropType
        };
        const res = await api.setting.menu.sort.put(reqData);
        if (res.code == 200) {
            ElMessage.success(res.message);
        } else {
            ElMessage.error(res.message);
        }
    } catch (error) {
        console.error('Error in setting/menu/index/nodeDrop action:', error);
    } finally {
        menuloading.value = false;
    }
};
// 新增菜单
const add = async (node, data) => {
    menuloading.value = true;
    var newMenuName = i18n.global.t('menu.newMenu') + newMenuIndex.value++;
    var newMenuData = {
        id: '',
        pid: data ? data.id : 0,
        name: newMenuName,
        path: "",
        component: "",
        title: newMenuName,
        type: "menu"
    };
    const res = await api.setting.menu.add.post(newMenuData);
    if (res.code !== 200) {
        ElMessage.error(res.message);
    }
    newMenuData.id = res.data.id;
    menuRef.value.append(newMenuData, node.data ? node : 0);
    menuRef.value.setCurrentKey(newMenuData.id);
    var pid = node.data ? node.data.id : 0;
    saveRef.value.setData(newMenuData, pid);
    menuloading.value = false;
};
// 删除菜单
const delMenu = async () => {
    var CheckedNodes = menuRef.value.getCheckedNodes();
    if (CheckedNodes.length == 0) {
        ElMessage.error(i18n.global.t('menu.selectMenu'));
        return false;
    };
    ElMessageBox.confirm(i18n.global.t('menu.confirmDeleteMenu'), i18n.global.t('common.tip'), {
        type: 'warning',
        confirmButtonText: i18n.global.t('common.confirm'),
        confirmButtonClass: 'el-button--danger',
    }).then(async () => {
        menuloading.value = true;
        var reqData = {
            ids: CheckedNodes.map(item => item.id)
        };
        const res = await api.setting.menu.delete.delete(reqData);
        if (res.code == 200) {
            CheckedNodes.forEach(item => {
                var node = menuRef.value.getNode(item);
                if (node.isCurrent) {
                    saveRef.value.setData({});
                };
                menuRef.value.remove(item);
            });
            ElMessage.success(res.message);
        } else {
            ElMessage.error(res.message);
        }
    }).catch(() => {
        return false;
    }).finally(() => {
        menuloading.value = false;
    });
};
</script>
<style scoped>
.menu:deep(.el-tree-node__label) {
    display: flex;
    flex: 1;
    height: 100%;
}

.custom-tree-node {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    height: 100%;
    padding-right: 24px;
}

.custom-tree-node .label {
    display: flex;
    align-items: center;
    ;
    height: 100%;
}

.custom-tree-node .label .el-tag {
    margin-left: 5px;
}

.custom-tree-node .do {
    display: none;
}

.custom-tree-node .do i {
    margin-left: 5px;
    color: #999;
}

.custom-tree-node .do i:hover {
    color: #333;
}

.custom-tree-node:hover .do {
    display: inline-block;
}
</style>